package org.wheel.plugins.toolkit.sql.capability;

import cn.hutool.core.util.ObjectUtil;
import org.wheel.plugins.toolkit.sql.helper.LambdaUtils;
import org.wheel.plugins.toolkit.sql.helper.SFunction;

import java.util.Collection;
import java.util.function.Consumer;

/**
 * 集合查询 查询子集对象
 * @param <W>
 * @param <T>
 */
public interface LambdaSubCollection<W extends LambdaSubCollection<W, T> , T> {

    /* ================== 获取集合下的某个属性 ================== */
    default <A> LambdaSubCollection<W, T> result(SFunction<A, ?> assocFn){
        return result(assocFn, (String) null);
    }
    default <A, B, C> LambdaSubCollection<W, T> result(SFunction<A, C> assocFn, SFunction<B, C> columnAlias){
        if(ObjectUtil.isNull(columnAlias)) {
            return result(assocFn, (String)null);
        }
        return result(assocFn, LambdaUtils.getFieldName(columnAlias));
    }

    <A> LambdaSubCollection<W, T> result(SFunction<A, ?> assocFn, String columnAlias);


    /* ================== 获取集合下的整个对象 ================== */
    default <A, B> LambdaSubCollection<W, T> association(Class<A> assocClass, SFunction<B, ?> assocFn){
        return association(assocClass, assocFn, null);
    }
    default <A, B> LambdaSubCollection<W, T> association(Class<A> assocClass, SFunction<B, ?> assocFn, Consumer<LambdaSubCollection<W, T>> nestedQuery){
        return association(null, assocClass, assocFn, nestedQuery);
    }
    <A, B> LambdaSubCollection<W, T> association(String tableAlias, Class<A> assocClass, SFunction<B, ?> assocFn, Consumer<LambdaSubCollection<W, T>> nestedQuery);

    /* ================== 获取集合下的整个对象集合 ================== */
    default <A, B, C> LambdaSubCollection<W, T> collection(Class<A> itemClass, SFunction<B, Collection<C>> collectionFn){
        return collection(itemClass, collectionFn, null);
    }
    default <A, B, C, D extends LambdaSubCollection<D, E>, E> LambdaSubCollection<W, T> collection(Class<A> itemClass, SFunction<B, Collection<C>> collectionFn,
                                                                                                   Consumer<LambdaSubCollection<D, E>> nestedQuery){
        return collection(null, itemClass, collectionFn, nestedQuery);
    }
    <A, B, C, D extends LambdaSubCollection<D, E>, E> LambdaSubCollection<W, T> collection(String tableAlias, Class<A> itemClass, SFunction<B, Collection<C>> collectionFn,
                                                                                                        Consumer<LambdaSubCollection<D, E>> nestedQuery);
}
